package com.sinodata.bsm.cicp.collector;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.IOUtils;

import org.apache.log4j.Logger;

import com.sinodata.bsm.cicp.exception.CollectorException;
import com.sinodata.bsm.common.vo.ResPropertyValue;

/**
 * 
 * <p>
 * Description: 采集程序静态类
 * </p>
 *
 * @author liulibo
 * @version 1.0

 * <p>
 * History: 
 *
 * Date                     Author         Version     Description
 * ---------------------------------------------------------------------------------
 * 2012-12-20 15:39:19      liulibo        1.0         To create
 * </p>
 *
 * @since 
 * @see
 */
public abstract class Collector implements ICollector {

    protected static final Logger logger = Logger.getLogger(Collector.class);

    protected Map<String, String> paramMap;

    protected long interval;

    private Map<Long, String> propMap;

    /**
     * 采集，传入采集参数、IP
     * 
     * @param paramMap
     * @param ip
     * @return
     * @throws CollectorException
     */
    public List<ResPropertyValue> collect(Map<String, String> paramMap, String ip) throws CollectorException {
        if (this.paramMap == null) {
            this.paramMap = paramMap;
        } else {
            this.paramMap.putAll(paramMap);
        }
        return collect(ip);
    }

    /**
     * 获取采集字段名
     * 
     * @return
     */
    public abstract String[] getPropMeta();

    /**
     * 获取采集参数名
     * 
     * @return
     */
    public abstract String[] getParamMeta();

    /**
     * 对指定ip的资源进行数据采集
     * 该方法由子类采集程序实现
     * @param ip
     * @return
     */
    @Override
    public abstract List<ResPropertyValue> collect(String ip) throws CollectorException;

    public Map<String, String> getParamMap() {
        return paramMap == null ? new HashMap<String, String>() : paramMap;
    }

    public void setParamMap(Map<String, String> paramMap) {
        this.paramMap = paramMap;
    }

    public void setPropMap(Map<Long, String> propMap) {
        this.propMap = propMap;
    }

    /**
     * 指标MAP数据构成:指标:字段/字段计算表达式
     * @return
     */
    public Map<Long, String> getPropMap() {
        return this.propMap;
    }

    public long getInterval() {
        return interval;
    }

    /**
     * 设置两次采集的时间间隔，确定是否
     * @param interval
     */
    public void setInterval(long interval) {
        this.interval = interval;
    }

    /**
     * 持久化临时数据，例如日志文件的采集，记录上次采集的状态。与getPersistentData相应使用
     * @param key
     * @param data
     * @throws IOException
     */
    protected void savePersistentData(String key, Serializable data) throws IOException {
        File saveDir = new File("save");
        if (!saveDir.exists()) {
            saveDir.mkdir();
        }
        String fileName = "save/" + key.hashCode() + ".od";
        File file = new File(fileName);
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                logger.error("failed to create new file", e);
            }
        }
        ObjectOutputStream oos = null;
        try {
            oos = new ObjectOutputStream(new FileOutputStream(file));
            oos.writeObject(data);
            oos.flush();
            oos.close();
        } finally {
            IOUtils.closeQuietly(oos);
        }
    }

    /**
     * 获取持久化临时数据，例如日志文件的采集，记录上次采集的状态。与savePersistentData相应使用
     * @param key
     * @return
     * @throws IOException
     * @throws ClassNotFoundException
     */
    protected Serializable getPersistentData(String key) throws IOException, ClassNotFoundException {
        String fileName = "save/" + key.hashCode() + ".od";
        File file = new File(fileName);
        if (!file.exists()) {
            return null;
        }
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new FileInputStream(file));
            Serializable val = (Serializable) ois.readObject();
            ois.close();
            return val;
        } finally {
            IOUtils.closeQuietly(ois);
        }
    }

}
